﻿using System.Xml;

namespace Rsdn.Janus.Core.Extensibility.UI
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Windows.Forms;
    using CoreServices.Extensibility;
    using SmartApp;

    public partial class ExtensionManagerForm : Form
    {
        private readonly ICommandContext commandContext;
       // private CheckedListBoxClickonceImpl checkedListBoxClickonceImpl;

        public ExtensionManagerForm(ICommandContext commandContext)
        {
            this.commandContext = commandContext;
            InitializeComponent();
            //checkedListBoxClickonceImpl = new CheckedListBoxClickonceImpl(checkedListBoxExtensions);
            checkedListBoxExtensions.CheckOnClick = true;
        }

        private void ExtensionManagerForm_Load(object sender, System.EventArgs e)
        {
            IJanusExtensionManager janusExtensionManager = commandContext.GetRequiredService<IJanusExtensionManager>();
            //IExtensionInfoProvider[] extensionInfoProviders = janusExtensionManager.GetInfoProviders();

            //foreach (IExtensionInfoProvider infoProvider in extensionInfoProviders)
            //{
            //    string displayName = infoProvider.GetDisplayName();
            //    checkedListBoxExtensions.Items.Add(displayName);

            //}
            XmlReaderSettings readerSettings = JanusExtensionManager.GetXmlReaderSettings(GetType());

            IEnumerable<ExtensionLoadInfo> extensionAssemblies = JanusExtensionManager.GetExtensionAssemblies(GetType(), Rsdn.Janus.EnvironmentHelper.GetJanusRootDir(), true);
            List<ExtensionInformation> extensionList = new List<ExtensionInformation>();
            foreach (ExtensionLoadInfo loadInfo in extensionAssemblies)
            {
                string descriptorFullName = loadInfo.Path + Path.DirectorySeparatorChar + JanusExtensionManager.ExtensionDescriptorFileName;
                Assembly assembly = Assembly.LoadFrom(loadInfo.ExtensionFullName);
                Type descriptionType =
                    assembly.GetTypes()
                        .Where(type => Attribute.IsDefined(type, typeof(ExtensionDescriptionProviderAttribute)))
                        .SingleOrDefault();

                if (descriptionType != null)
                {
                    IExtensionInfoProvider instance = (IExtensionInfoProvider) Activator.CreateInstance(descriptionType);
                    string displayName = instance.GetDisplayName();
                    extensionList.Add(new ExtensionInformation(displayName, descriptorFullName, loadInfo.DescriptionNode));
                }
            }

            foreach (ExtensionInformation information in extensionList)
            {
                checkedListBoxExtensions.Items.Add(information, information.IsLoadAllowed);
            }

            if (checkedListBoxExtensions.Items.Count > 0)
            {
                checkedListBoxExtensions.SelectedIndex = 0;
            }
            //OwnerDocument 
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void buttonOk_Click(object sender, EventArgs e)
        {
            Dictionary<XmlDocument, ExtensionInformation> extensionsXml = new Dictionary<XmlDocument, ExtensionInformation>();
            for (int i = 0; i < checkedListBoxExtensions.Items.Count; i++)
            {
                ExtensionInformation item = checkedListBoxExtensions.Items[i] as ExtensionInformation;
                CheckState itemCheckState = checkedListBoxExtensions.GetItemCheckState(i);
                if (item != null)
                {
                    item.SetLoadAllowed(itemCheckState == CheckState.Checked);
                    if (!extensionsXml.ContainsKey(item.OwnerDocument))
                    {
                        extensionsXml.Add(item.OwnerDocument, item);
                    }
                }
            }

            foreach (KeyValuePair<XmlDocument, ExtensionInformation> pair in extensionsXml)
            {
                string extDescriptorFullName = pair.Value.ExtDescriptorFullName;
                if (pair.Value.Modified)
                {
                    pair.Key.Save(extDescriptorFullName);
                }
            }
        }


        private class ExtensionInformation
        {
            private string description;
            private string extDescriptorFullName;
            private XmlElement xmlElement;
            private bool prevLoad;
            private bool modified;

            public ExtensionInformation(string description, string extDescriptorFullName, XmlElement xmlElement)
            {
                this.description = description;
                this.extDescriptorFullName = extDescriptorFullName;
                this.xmlElement = xmlElement;
                prevLoad = IsLoadAllowed;
                modified = false;
            }


            public void SetLoadAllowed(bool loadAllowed)
            {
                if (prevLoad != loadAllowed)
                {
                    JanusExtensionManager.SetLoadAttributeValue(xmlElement, loadAllowed);
                    modified = true;
                }
            }

            public override string ToString()
            {
                return description;
            }

            public bool Modified
            {
                get { return modified; }
            }

            public XmlDocument OwnerDocument
            {
                get
                {
                    return xmlElement.OwnerDocument;
                }

            }

            public string Description
            {
                get { return description; }
            }

            public string ExtDescriptorFullName
            {
                get { return extDescriptorFullName; }
            }

            public bool IsLoadAllowed
            {
                get
                {
                    string loadAttribute = JanusExtensionManager.GetLoadAttributeValue(xmlElement);
                    return JanusExtensionManager.IsLoadAllowed(loadAttribute);
                }
            }

        }

    }
}
